#ifndef __PARSER_TREE_NODE__
#define __PARSER_TREE_NODE__

#include "Atom.h"
#include "Util.h"
#define ParserTree ParserTreeNode
#define List ParserTreeNode

enum TreeType{LIST_TREE, DOT_TREE, NIL_TREE, ATOM_TREE, NONE_TREE};

class ParserTreeNode
{
public:
	ParserTreeNode();
	ParserTreeNode(std::string str);
	ParserTreeNode(int number);
	~ParserTreeNode(void);
	TreeType treeType;

private:
	// Each node contains an atom token
	Atom atom;
	// left child
	ParserTreeNode* leftChild;
	// right child
	ParserTreeNode* rightChild;


public:
	// add a left/right child 
	ParserTreeNode* addChild(bool leftOrRight, ParserTreeNode* node);
	// add a left/right child whose atom is a number
	ParserTreeNode* addChild(bool leftOrRight, int number);
	// add a left/right child whose atom is a literal
	ParserTreeNode* addChild(bool leftOrRight, std::string str);
	// get the left/right child
	ParserTreeNode* getChild(bool leftOrRight);
	// get the atom
	Atom getAtom()
	{return this->atom;};
	// is a node an atom(leaf node)
	bool isDOT()
	{return this->atom.type == DOT_ATOM;};
	bool isLiteral()
	{return this->atom.type == LITERAL_ATOM;};
	bool isNumber()
	{return this->atom.type == NUMBER_ATOM;};
	bool isNIL()
	{return isLiteral() && Util::isEqual(getAtom().str, "NIL");}
	bool nilRightChild()	//	if right child is a nil
	{return !rightChild || (rightChild->isNIL());}
	// copy a parser tree
	ParserTreeNode* copy();

};

#endif
